import { _decorator, Node, instantiate, Vec2, tween, UITransform, v3, v2 } from 'cc';
// import RowFallClear_Cell from "./Cell";
// import GamePlayPanel from "../UI/GamePlayPanel";
// import RowFallClear_GameManager, { GameState } from "../Manager/GameManager";
import RowFallClear_AudioManager from '../Manager/RowFallClear_AudioManager';
import RowFallClear_GamePlayPanel from '../UI/RowFallClear_GamePlayPanel';
import RowFallClear_GameManager, { GameState } from '../Manager/RowFallClear_GameManager';
import RowFallClear_Cell from './RowFallClear_Cell';
import RowFallClear_Grid from './RowFallClear_Grid';
import { RowFallClear_GameData } from '../Data/RowFallClear_GameData';
// import AudioManager from "../Manager/AudioManager";

const { ccclass, property } = _decorator;

@ccclass('RowFallClear_CellFunctions')
export default class RowFallClear_CellFunctions {
    // public static CreateGrid(x: number, y: number, cellSize: number) {
    //     let node = instantiate(RowFallClear_GameManager.Instance.Prefab_Grid);
    //     node.parent = RowFallClear_GameManager.Instance.Node_2D;
    //     node.setPosition(0, 0);
    //     node.getComponent(UITransform).width = cellSize;
    //     node.getComponent(UITransform).height = cellSize;
    //     var pos_x = cellSize * x - RowFallClear_GameManager.Instance.width / 2 + cellSize / 2;
    //     var pos_y = cellSize * y - RowFallClear_GameManager.Instance.height_screen / 2 + cellSize / 2 + RowFallClear_GameManager.Instance.padding_bottom;
    //     node.setPosition(pos_x, pos_y);

    //     return node;
    // }

    //    /** 创建格子 */
    static CreateGrid(_id: number, x: number, y: number) {
        const node: Node = instantiate(RowFallClear_GameManager.Instance.Prefab_Grid);
        const scrGrid: RowFallClear_Grid = node.getComponent(RowFallClear_Grid);
        RowFallClear_GameManager.Instance.Root_grid.addChild(node);
        scrGrid.init(_id, x, y);
        return scrGrid;
    }

    public static CreateCell(id: number, x: number, y: number, cellList: Array<Array<RowFallClear_Cell>>) {
        let node = instantiate(RowFallClear_GameManager.Instance.Prefab_Cell);
        let cell: RowFallClear_Cell = node.getComponent(RowFallClear_Cell);
        cell.isNew = true;
        if (cellList != null) {
            cellList[x][y] = cell;
            cell.Init(id, x, y);
        }

        cell.RefreshUI();

        return cell;
    }
    //    //生成最上面一行元素
    //    //目前采用一种保底机制，保证每种元素至少随机出一个
    public static CreateTopLine(row: number = 0) {
        RowFallClear_GameManager.Instance.timer = 0;
        let y: number = row - 1;
        for (let x = 0; x <= RowFallClear_GameData.col - 1; x++) {
            let id: number = Math.floor(Math.random() * (RowFallClear_GameManager.Instance.type_count - 1)) + 1;
            let cell: RowFallClear_Cell = RowFallClear_CellFunctions.CreateCell(id, x, y, RowFallClear_GameManager.Instance.cellList);
        }
        //        //目前采用一种保底机制，保证每种元素至少随机出一个
        //        // 炸弹10次出现一次，且一次出现一个
        let count: number = RowFallClear_GameManager.Instance.type_count - 1
        let ran: number = Math.random();
        if (ran <= 0.3) {
            count = RowFallClear_GameManager.Instance.type_count; //出现炸弹
        }
        else {
            count = RowFallClear_GameManager.Instance.type_count - 1;
        }
        let items: Array<number> = RowFallClear_CellFunctions.GetRandomArray(count, 0, RowFallClear_GameData.col - 1);
        for (let i = 0; i < items.length; i++) {
            let x: number = items[i];
            let cell: RowFallClear_Cell = RowFallClear_GameManager.Instance.cellList[x][y];
            cell.id = i + 1;
            cell.RefreshUI();
        }
    }
    //    // 获取当前操作的一行
    public static GetCurrentMovingRow(): number {
        let row: number = 0;
        for (let x = 0; x <= RowFallClear_GameData.col - 1; x++) {
            for (let y = RowFallClear_GameData.row - 1 + 1; y >= 0; y--) {
                let cell: RowFallClear_Cell = RowFallClear_GameManager.Instance.cellList[x][y];
                if (cell != null) {
                    row = y + 1;
                    return row;
                }
            }
        }
        return row;
    }
    //    // 左右移动
    public static MoveLefOrRight(dir: number) {
        if (RowFallClear_GameManager.Instance.gameState != GameState.Free) {
            return;
        }

        RowFallClear_AudioManager.Instance.audio_move.play();
        //        // AudioManager.Instance.Play(AudioManager.Instance.audio_move);
        let topIdList: Array<RowFallClear_Cell> = new Array<RowFallClear_Cell>();
        let copyIdList: Array<number> = new Array<number>();

        let y = RowFallClear_CellFunctions.GetCurrentMovingRow() - 1;
        for (let x = 0; x <= RowFallClear_GameData.col - 1; x++) {
            let cell: RowFallClear_Cell = RowFallClear_GameManager.Instance.cellList[x][y];
            topIdList[x] = cell;
            copyIdList[x] = cell.id;
        }
        for (let x = 0; x <= topIdList.length - 1; x++) {
            let cell: RowFallClear_Cell = topIdList[x];
            let nextIndex: number = x;
            if (dir == -1) {
                nextIndex = x + 1;
                if (nextIndex > topIdList.length - 1) {
                    nextIndex = 0;
                }
            }
            else if (dir == 1) {
                nextIndex = x - 1;
                if (nextIndex < 0) {
                    nextIndex = topIdList.length - 1;
                }
            }

            cell.id = copyIdList[nextIndex];
            cell.RefreshUI();
        }

        RowFallClear_GameData.IsCanOperate = true;
    }

    //    //通过x和y获得一个指定Cell
    public static GetCell(x: number, y: number): RowFallClear_Cell {
        let cell: RowFallClear_Cell = null;
        if (x >= 0 && x <= RowFallClear_GameData.col - 1 &&
            y >= 0 && y <= RowFallClear_GameData.row - 1) {
            cell = RowFallClear_GameManager.Instance.cellList[x][y];
        }
        return cell;
    }
    public static Check(cell: RowFallClear_Cell, list: Array<RowFallClear_Cell>): Array<RowFallClear_Cell> {
        if (list == null) {
            list = new Array<RowFallClear_Cell>();
        }
        if (cell == null) {
            return null;
        }
        if (list.indexOf(cell) != -1) {
            return list;
        }
        else {
            list.push(cell);
        }
        let x: number = cell.x;
        let y: number = cell.y;
        let cell_up: RowFallClear_Cell = RowFallClear_CellFunctions.GetCell(x, y + 1);
        let cell_down: RowFallClear_Cell = RowFallClear_CellFunctions.GetCell(x, y - 1);
        let cell_left: RowFallClear_Cell = RowFallClear_CellFunctions.GetCell(x - 1, y);
        let cell_right: RowFallClear_Cell = RowFallClear_CellFunctions.GetCell(x + 1, y);
        if (cell_up != null && cell.id == cell_up.id) {
            RowFallClear_CellFunctions.Check(cell_up, list);
        }
        if (cell_down != null && cell.id == cell_down.id) {
            RowFallClear_CellFunctions.Check(cell_down, list);
        }
        if (cell_left != null && cell.id == cell_left.id) {
            RowFallClear_CellFunctions.Check(cell_left, list);
        }
        if (cell_right != null && cell.id == cell_right.id) {
            RowFallClear_CellFunctions.Check(cell_right, list);
        }

        return list;
    }
    //    //检测所有相邻并有相同id元素的Cell，组成列表
    public static GetAllSameList(): Array<Array<RowFallClear_Cell>> {
        let lists: Array<Array<RowFallClear_Cell>> = new Array<Array<RowFallClear_Cell>>();
        for (let x = 0; x <= RowFallClear_GameData.col - 1; x++) {
            for (let y = 0; y <= RowFallClear_GameData.row - 1; y++) {
                let cell: RowFallClear_Cell = RowFallClear_GameManager.Instance.cellList[x][y];
                let isContains: boolean = false;
                lists.forEach(function (list) {
                    if (list != null && list.indexOf(cell) != -1) {
                        isContains = true;
                    }
                });

                if (isContains == false) {
                    let sameList: Array<RowFallClear_Cell> = RowFallClear_CellFunctions.Check(cell, null);
                    lists.push(sameList);
                }
            }
        }
        return lists;
    }
    //    //三消
    public static KillAllSameList(): boolean {
        RowFallClear_GameManager.Instance.isKill = false;
        let lists: Array<Array<RowFallClear_Cell>> = RowFallClear_CellFunctions.GetAllSameList();
        if (lists != null) {
            lists.forEach(function (list) {
                if (list != null) {
                    if (list.length >= 3) {
                        RowFallClear_GameManager.Instance.isKill = true;
                        RowFallClear_GameManager.Instance.killCellList.push(list);
                    }
                }
            });
        }
        if (RowFallClear_GameManager.Instance.isKill) {
            RowFallClear_CellFunctions.DelayFunction(
                () => {
                    let list = RowFallClear_GameManager.Instance.killCellList[0];
                    let removed = RowFallClear_GameManager.Instance.killCellList.splice(0, 1);

                    RowFallClear_GameManager.Instance.score += list.length;
                    RowFallClear_GamePlayPanel.Instance.RefreshScore(RowFallClear_GameManager.Instance.score);
                    RowFallClear_AudioManager.Instance.audio_disappear.play();
                    let item_cell: RowFallClear_Cell = list[0];
                    list.forEach(function (item_cell) {
                        if (list != null && list.indexOf(item_cell) != -1) {
                            item_cell.Dead();
                        }
                    });
                },
                () => {
                    RowFallClear_GameManager.Instance.scheduleOnce(function () {
                        RowFallClear_GameManager.Instance.ChangeStateMachine(GameState.Bomb);
                    }, 0.5);
                }, RowFallClear_GameManager.Instance.killCellList.length, 0.5);
        }
        else {
            RowFallClear_GameManager.Instance.ChangeStateMachine(GameState.Bomb);
        }
        return RowFallClear_GameManager.Instance.isKill;
    }

    //    //操作并所有下移
    public static Bomb(): boolean {
        let isBomb: boolean = false;
        for (let x = 0; x <= RowFallClear_GameData.col - 1; x++) {
            for (let y = 0; y <= RowFallClear_GameData.row - 1; y++) {
                let cell: RowFallClear_Cell = RowFallClear_GameManager.Instance.cellList[x][y];
                if (cell != null && cell.id == 6) {
                    RowFallClear_GameManager.Instance.isKill = true;
                    isBomb = true;
                    RowFallClear_CellFunctions.Explore9(cell.x, cell.y);
                }
            }
        }
        if (isBomb) {
            RowFallClear_GameManager.Instance.scheduleOnce(function () {
                RowFallClear_GameManager.Instance.ChangeStateMachine(GameState.Fall);
            }, 0.4);
        }
        else {
            // GameManager.Instance.RoundEnd();
            RowFallClear_GameManager.Instance.ChangeStateMachine(GameState.Fall);
        }

        return RowFallClear_GameManager.Instance.isKill;
    }

    //操作并所有下移
    public static ControlMoveDown() {
        if (RowFallClear_GameManager.Instance.gameState == GameState.Free) {
            RowFallClear_GameManager.Instance.ChangeStateMachine(GameState.Fall);
        }
    }

    //所有下移
    public static MoveDownAllCell(): boolean {
        let isMove: boolean = false;
        for (let x = 0; x <= RowFallClear_GameData.col - 1; x++) {
            for (let y = 0; y <= RowFallClear_GameData.row - 1 + 1; y++) {
                let oneMove: boolean = RowFallClear_CellFunctions.MoveDownCell(x, y);
                if (oneMove == true) {
                    isMove = true;
                }
            }
        }
        if (isMove == true) {
            RowFallClear_AudioManager.Instance.audio_fall.play();
        }
        else {
            RowFallClear_GameManager.Instance.RoundEnd();
        }
        return isMove;
    }

    //    //下移到不能下移的位置
    public static MoveDownCell(x: number, y: number): boolean {
        //        // TipPanel.Instance.Open("MoveDownCell");
        let isMove: boolean = false;
        let cell: RowFallClear_Cell = RowFallClear_GameManager.Instance.cellList[x][y];
        if (cell != null) {
            let firstEmptyCell_Y: number = RowFallClear_CellFunctions.GetFirstEmptyCellY(x);
            if (firstEmptyCell_Y >= 0 && cell.y > firstEmptyCell_Y) {
                isMove = true;
                RowFallClear_GameManager.Instance.movingCellList.push(cell);
                let y = cell.y;
                cell.Set(x, firstEmptyCell_Y);

                let pos: Vec2 = RowFallClear_CellFunctions.GetPosition(cell.x, firstEmptyCell_Y);

                tween(cell.node)
                    // .to(0.08 * (y - firstEmptyCell_Y), { y: pos.y })
                    .to(0.08 * (y - firstEmptyCell_Y), { position: v3(cell.node.position.x, pos.y) })
                    .call(() => {
                        let index = RowFallClear_GameManager.Instance.movingCellList.indexOf(cell);
                        if (index != -1) {
                            let removed = RowFallClear_GameManager.Instance.movingCellList.splice(index, 1);
                        }
                        if (RowFallClear_GameManager.Instance.movingCellList.length <= 0) {
                            RowFallClear_GameManager.Instance.scheduleOnce(function () {
                                // TipPanel.Instance.Open("KillAllSameList");
                                // CellFunctions.KillAllSameList();
                                RowFallClear_GameManager.Instance.ChangeStateMachine(GameState.Match);
                            }, 0.2);
                        }
                    })
                    .start()
            }
        }

        return isMove;
    }

    //获取从下到上一列中第一个为空的Cell
    public static GetFirstEmptyCellY(x: number): number {
        let firstEmptyCell_Y: number = -1;

        for (let y = 0; y <= RowFallClear_GameData.row - 1; y++) {
            let item_cell: RowFallClear_Cell = RowFallClear_GameManager.Instance.cellList[x][y];
            if (item_cell == null) {
                firstEmptyCell_Y = y;
                break;
            }
        }

        return firstEmptyCell_Y;
    }

    //清除所有
    public static ClearAll() {
        if (RowFallClear_GameManager.Instance.cellList == null || RowFallClear_GameManager.Instance.cellList.length == 0) {
            return;
        }

        for (let x = 0; x <= RowFallClear_GameData.col - 1; x++) {
            for (let y = 0; y <= RowFallClear_GameData.row - 1 + RowFallClear_GameManager.Instance.add_row; y++) {
                let cell: RowFallClear_Cell = RowFallClear_GameManager.Instance.cellList[x][y];
                if (cell != null) {
                    cell.Dead();
                }
            }
        }
    }
    //    //刷新所有
    public static RefreshAll() {
        if (RowFallClear_GameManager.Instance.cellList == null || RowFallClear_GameManager.Instance.cellList.length == 0) {
            return;
        }
        for (let x = 0; x <= RowFallClear_GameData.col - 1; x++) {
            for (let y = 0; y <= RowFallClear_GameData.row - 1 + RowFallClear_GameManager.Instance.add_row; y++) {
                let cell: RowFallClear_Cell = RowFallClear_GameManager.Instance.cellList[x][y];
                if (cell != null) {
                    cell.initPosition();
                    // cell.RefreshPos();
                    cell.RefreshUI();
                }
            }
        }
    }
    //    //刷新所有
    public static SetAllNotNew() {
        if (RowFallClear_GameManager.Instance.cellList == null || RowFallClear_GameManager.Instance.cellList.length == 0) {
            return;
        }
        for (let x = 0; x <= RowFallClear_GameData.col - 1; x++) {
            for (let y = 0; y <= RowFallClear_GameData.row - 1; y++) {
                let cell: RowFallClear_Cell = RowFallClear_GameManager.Instance.cellList[x][y];
                if (cell != null) {
                    cell.isNew = false;
                }
            }
        }
    }
    //    // 从minNum到maxNum取其中Number个
    //    // Number随机数个数
    //    // minNum随机数下限
    //    // maxNum随机数上限
    public static GetRandomArray(Number: number, minNum: number, maxNum: number): Array<number> {
        let j: number;
        let b: Array<number> = new Array<number>();
        for (let j = 0; j < Number; j++) {
            //            // UnityEngine.Random.Range(minNum, maxNum + 1);
            let i: number = Math.floor(Math.random() * maxNum) + minNum;
            let num: number = 0;
            for (let k = 0; k < j; k++) {
                if (b[k] == i) {
                    num = num + 1;
                }
            }
            if (num == 0) {
                b[j] = i;
            }
            else {
                j = j - 1;
            }
        }
        return b;
    }
    //    // 获取最高的y值
    public static GetMaxY(): number {
        let maxY: number = 0;
        for (let x = 0; x <= RowFallClear_GameData.col - 1; x++) {
            for (let y = 0; y <= RowFallClear_GameData.row - 1; y++) {
                let cell: RowFallClear_Cell = RowFallClear_GameManager.Instance.cellList[x][y];
                if (cell != null && cell.isNew == false && cell.y > maxY && cell.y <= RowFallClear_GameData.row - 1) {
                    maxY = y;
                }
            }
        }
        return maxY;
    }
    //    // 获取位置
    public static GetPosition(_x: number, _y: number): Vec2 {
        let pos: Vec2 | null = null;
        let x = -RowFallClear_GameData.W / 2 + RowFallClear_GameData.size / 2 + RowFallClear_GameData.size * _x;
        let y = -RowFallClear_GameData.H / 2 + RowFallClear_GameData.size / 2 + RowFallClear_GameData.size * _y;
        pos = v2(x, y);
        return pos;

        // let pos: Vec2 | null = null;
        // var pos_x = RowFallClear_GameData.size * _x - RowFallClear_GameManager.Instance.width / 2 + RowFallClear_GameData.size / 2;
        // var pos_y = RowFallClear_GameData.size * _y - RowFallClear_GameManager.Instance.height_screen / 2 + RowFallClear_GameData.size / 2 + RowFallClear_GameManager.Instance.padding_bottom;
        // pos = new Vec2(pos_x, pos_y);
        // return pos;
    }
    //    //9宫格爆炸
    public static Explore9(_x: number, _y: number) {
        if (RowFallClear_GameManager.Instance.cellList == null || RowFallClear_GameManager.Instance.cellList.length == 0) {
            return;
        }
        for (let x = _x - 1; x <= _x + 1; x++) {
            for (let y = _y - 1; y <= _y + 1; y++) {
                let cell: RowFallClear_Cell = RowFallClear_CellFunctions.GetCell(x, y);
                if (cell != null) {
                    cell.Dead();
                }
            }
        }
        RowFallClear_AudioManager.Instance.audio_explore.play();
        //        // AudioManager.Instance.Play(AudioManager.Instance.audio_explore);
    }
    //    //延时函数
    public static DelayFunction(_callback: Function, _complete: Function, _loop: number = 1, _duration: number = 1) {
        if (_callback) {
            _callback();
        }
        if (_loop <= 1) {
            if (_complete) {
                _complete();
            }
            return;
        }

        let count = 1;
        let callback = function () {
            if (_callback) {
                _callback();
            }
            if (count >= _loop - 1) {
                RowFallClear_GameManager.Instance.unschedule(callback);
                if (_complete) {
                    _complete();
                }
            }
            count++;
        }
        RowFallClear_GameManager.Instance.schedule(callback, _duration);
    }
}